package alt.djudge.frontend.server.servlets.gwt;

import java.util.List;

import org.apache.log4j.Logger;

import alt.djudge.frontend.client.rpc.DJudgeGWTAdminService;
import alt.djudge.frontend.server.datatypes.AbstractEntry;
import alt.djudge.frontend.server.models.CoreInterface;
import alt.djudge.frontend.server.models.ModelsFactory;
import alt.djudge.frontend.shared.dto.admin.AdminDTOEntry;


public class DJudgeGWTAdminServiceImpl extends DJudgeGwtRpcServlet implements DJudgeGWTAdminService
{
	private static final long serialVersionUID = 1L;
	
	private static final Logger log = Logger.getLogger(DJudgeGWTAdminServiceImpl.class);

/*	@Override
	public UserEntryDTO[] getUsers(int page)
	{
		List<UserEntry> users = UsersModel.getAllEntries();
		int size = users.size();
		UserEntryDTO[] gwtUsers =  new UserEntryDTO[size];
		int i = 0;
		for (UserEntry userEntry : users)
			gwtUsers[i++] = userEntry.asDTO();
		return gwtUsers;
	}

	@Override
	public ContestEntryDTO[] getContests(int page)
	{
		List<ContestEntry> users = ContestsModel.getAllEntries();
		int size = users.size();
		ContestEntryDTO[] gwtUsers =  new ContestEntryDTO[size];
		int i = 0;
		for (ContestEntry userEntry : users)
		{
			gwtUsers[i++] = userEntry.asDTO();
		}
		return gwtUsers;
	}

	@Override
	public SubmissionEntryDTO[] getSubmissions(int page)
	{
		List<SubmissionEntry> users = SubmissionsModel.getAllSubmissions();
		int size = users.size();
		SubmissionEntryDTO[] gwtUsers = new SubmissionEntryDTO[size];
		int i = 0;
		for (SubmissionEntry userEntry : users)
			gwtUsers[i++] = userEntry.asDTO();
		return gwtUsers;
	}

	@Override
	public LanguageEntryDTO[] getLanguages(int page)
	{
		List<LanguageEntry> users = LanguagesModel.getAllEntries();
		int size = users.size();
		LanguageEntryDTO[] gwtUsers = new LanguageEntryDTO[size];
		int i = 0;
		for (LanguageEntry userEntry : users)
			gwtUsers[i++] = userEntry.asDTO();
		return gwtUsers;
	}*/

	@Override
	public AdminDTOEntry copyEntry(AdminDTOEntry dtoEntry)
	{
		Class<? extends AdminDTOEntry> clazz = dtoEntry.getClass();
		Long entryId = dtoEntry.getId();
		CoreInterface<? extends AbstractEntry> entryModel = ModelsFactory.getModelForDTOClass(clazz); 
		AbstractEntry entry = entryModel.getEntry(entryId);
		if (entry != null)
		{
			log.trace("Copying " + clazz.getSimpleName() + " " + entryId);
			AbstractEntry newEntry = entryModel.newEntry();
			newEntry.fromDTO(entry.asAdminDTO());
			if (newEntry.makePersistent())
				return newEntry.asAdminDTO();
			return null;
		}
		else
		{
			log.trace("Copying " + clazz.getSimpleName() + " " + entryId + " failed");
		}
		return null;
	}

	@Override
	public AdminDTOEntry editEntry(AdminDTOEntry dtoEntry)
	{
		Class<? extends AdminDTOEntry> clazz = dtoEntry.getClass();
		Long entryId = dtoEntry.getId();
		CoreInterface<? extends AbstractEntry> entryModel = ModelsFactory.getModelForDTOClass(clazz); 
		AbstractEntry entry = entryModel.getEntry(entryId);
		if (entry != null)
		{
			log.trace("Editing " + clazz.getSimpleName() + " " + entryId);
			log.trace(dtoEntry.toString());
			entry.fromDTO(dtoEntry);
			if (entry.makePersistent())
				return entry.asAdminDTO();
			return null;
		}
		else
		{
			log.trace("Editing " + clazz.getSimpleName() + " " + entryId + " - No such entry");
		}
		return null;
	}
	
	@Override
	public AdminDTOEntry createEntry(AdminDTOEntry dtoEntry)
	{
		Class<? extends AdminDTOEntry> clazz = dtoEntry.getClass();
		CoreInterface<? extends AbstractEntry> entryModel = ModelsFactory.getModelForDTOClass(clazz); 
		AbstractEntry entry = entryModel.newEntry();		
		log.trace("Create entry " + entry.getClass());
		entry.fromDTO(dtoEntry);
		if (entry.makePersistent())
			return entry.asAdminDTO();
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public AdminDTOEntry[] getEntries(String className, int page)
	{
		Class<AdminDTOEntry> clazz = null;
		try
		{
			clazz = (Class<AdminDTOEntry>) Class.forName(className);
		}
		catch (ClassNotFoundException e)
		{
			log.fatal(e);
		}
		CoreInterface<? extends AbstractEntry> entryModel = ModelsFactory.getModelForDTOClass(clazz);
		List<? extends AbstractEntry> entries = entryModel.getAllEntries();
		int size = entries.size();
		AdminDTOEntry[] dtoEntries = new AdminDTOEntry[size];
		int i = 0;
		for (AbstractEntry entry : entries)
			dtoEntries[i++] = entry.asAdminDTO();
		return dtoEntries;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean setEntryField(final String className, final long entryId, final int field, final boolean value)
	{
		Class<AdminDTOEntry> clazz = null;
		try
		{
			clazz = (Class<AdminDTOEntry>) Class.forName(className);
		}
		catch (ClassNotFoundException e)
		{
			log.fatal(e);
		}
		CoreInterface<? extends AbstractEntry> entryModel = ModelsFactory.getModelForDTOClass(clazz);
		AbstractEntry entry = entryModel.getEntry(entryId);
		if (field == FIELD_VISIBLE)
		{
			entry.setVisible(value);
		}
		else if (field == FIELD_ACTIVE)
		{
			entry.setActive(value);
		}
		else
		{
			entry.setDeleted(value);
		}
		entry.makePersistent();
		return !value;
	}
}
